#include <defs.h>
#include <bwio.h>
#include <user.h>
#include <nameserver.h>
#include <clockserver.h>
#include <string.h>

int Create( int priority, void (*func) () ) {
  asm volatile ("swi %0" : : "i" (SYSCALL_CREATE));
  // NOTE: this is essentially a hack to avoid a compiler warning.
  int ret;
  asm volatile ("mov %0, r0" : "=ir" (ret));
  return ret;
}

int MyTid() {
  asm volatile ("swi %0" : : "i" (SYSCALL_MY_TID));
  int ret;
  asm volatile ("mov %0, r0" : "=ir" (ret));
  return ret;
}

int MyParentTid() {
  asm volatile ("swi %0" : : "i" (SYSCALL_MY_PARENT_TID));
  int ret;
  asm volatile ("mov %0, r0" : "=ir" (ret));
  return ret;
}

void Pass() {
  asm volatile ("swi %0" : : "i" (SYSCALL_PASS));
}

void Exit() {
  asm volatile ("swi %0" : : "i" (SYSCALL_EXIT));
}

void FingerOfDeath() {
  asm volatile ("swi %0" : : "i" (SYSCALL_FINGER_OF_DEATH));
}

int Send( int tid, char *msg, int msglen, char *reply, int replylen ) {
  asm volatile ("swi %0" : : "i" (SYSCALL_SEND));
  int ret;
  asm volatile ("mov %0, r0" : "=ir" (ret));
  return ret;
}

int Receive( int *tid, char *msg, int len ) {
  asm volatile ("swi %0" : : "i" (SYSCALL_RECEIVE));
  int ret;
  asm volatile ("mov %0, r0" : "=ir" (ret));
  return ret;
}

int Reply( int tid, char *reply, int len ) {
  asm volatile ("swi %0" : : "i" (SYSCALL_REPLY));
  int ret;
  asm volatile ("mov %0, r0" : "=ir" (ret));
  return ret;
}

int RegisterAs(char *name) {
  name_req request;
  request.type = REGISTER_AS_REQUEST;
  StringCopy(request.name, name);
  int reply;
  
	Send(1, (char*)( &request ), sizeof(name_req),
      (char*)( &reply ), sizeof(int));
	return reply;
}

int WhoIs(char *name) {
  name_req request;
  request.type = WHO_IS_REQUEST;
  StringCopy(request.name, name);
  int reply;
  
	Send(1, (char*)( &request ), sizeof(name_req),
      (char*)( &reply ), sizeof(int));
	return reply;
}

int Delay(int ticks) {
  int clockserver_tid = WhoIs("clock-server");
  clock_req msg;
  msg.type = DELAY_REQUEST;
  msg.ticks = ticks;
  Send(clockserver_tid, (char*)( &msg ), sizeof(clock_req), NULL, 0);
  return SUCCESS;
}

int Time() {
  int clockserver_tid = WhoIs("clock-server");
  clock_req msg;
  msg.type = TIME_REQUEST;
  int time;
  Send(clockserver_tid, (char*)( &msg ), sizeof(clock_req),
      (char*)( &time ), sizeof(int));
  return time;
}

int DelayUntil(int ticks) {
  int clockserver_tid = WhoIs("clock-server");
  clock_req msg;
  msg.type = DELAY_UNTIL_REQUEST;
  msg.ticks = ticks;
  Send(clockserver_tid, (char*)( &msg ), sizeof(clock_req), NULL, 0);
  return SUCCESS;
}

int AwaitEvent( int eventid, char *event, int eventlen ) {
  asm volatile ("swi %0" : : "i" (SYSCALL_AWAIT_EVENT));
  int ret;
  asm volatile ("mov %0, r0" : "=ir" (ret));
  return ret;
}

int ParamTest(int a0, int a1, int a2, int a3, int a4) {
  asm volatile ("swi %0" : : "i" (SYSCALL_PARAM_TEST));
  int ret;
  asm volatile ("mov %0, r0" : "=ir" (ret));
  return ret;
}
